package com.wudimeng.syll.utils;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
/**
 * @Author laohei
 * @Date 2021/1/9 9:50
 * @Version 1.0
 */
public class ConvertBean {
//    方法1：把JavaBean的from的值自动set给to，省略了自己从from中get然后再set给to
    public static Object convertBean2Bean(Object from, Object to) {
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(to.getClass());
            PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor p : ps) {
                Method getMethod = p.getReadMethod();
                Method setMethod = p.getWriteMethod();
                if (getMethod != null && setMethod != null) {
                    try {
                        Object result = getMethod.invoke(from);
                        setMethod.invoke(to, result);
                    } catch (Exception e) {
                        // 如果from没有此属性的get方法，跳过
                        continue;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return to;
    }

    /**
     * 不支持to继承(to是其他bean的子类)
     */
    public static Object coverBean2Bean(Object from, Object to) {
        Class fClass = from.getClass();
        Class tClass = to.getClass();
        // 拿to所有属性（如果有继承，父类属性拿不到）
        Field[] cFields = tClass.getDeclaredFields();
        try {
            for (Field field : cFields) {
                String cKey = field.getName();
                // 确定第一个字母大写
                cKey = cKey.substring(0, 1).toUpperCase() + cKey.substring(1);

                Method fMethod;
                Object fValue;
                try {
                    fMethod = fClass.getMethod("get" + cKey);// public方法
                    fValue = fMethod.invoke(from);// 取getfKey的值
                } catch (Exception e) {
                    // 如果from没有此属性的get方法，跳过
                    continue;
                }

                try {
                    // 用fMethod.getReturnType()，而不用fValue.getClass()
                    // 为了保证get方法时，参数类型是基本类型而传入对象时会找不到方法
                    Method cMethod = tClass.getMethod("set" + cKey, fMethod.getReturnType());
                    cMethod.invoke(to, fValue);
                } catch (Exception e) {
                    // 如果to没有此属性set方法，跳过
                    continue;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return to;
    }
}
